package com.greenline.push.service.core.utils.xmpp;


import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.XMPPError;
import org.jivesoftware.smack.util.StringUtils;

/**
 * @Type MessageExtend
 * @Desc
 * @author kelei.huang
 * @date 2014年5月8日
 * @Version V1.0
 */
public class MyMessage extends Packet {
	private Type type = Type.normal;
	private String thread = null;
	private String language;
	private final Set<Subject> subjects = new HashSet<Subject>();
	private final Set<Body> bodies = new HashSet<Body>();

	public MyMessage() {
	}

	public MyMessage(String paramString) {
		setTo(paramString);
	}

	public MyMessage(String paramString, Type paramType) {
		setTo(paramString);
		this.type = paramType;
	}

	public Type getType() {
		return this.type;
	}

	public void setType(Type paramType) {
		if (paramType == null) {
			throw new IllegalArgumentException("Type cannot be null.");
		}
		this.type = paramType;
	}

	public String getSubject() {
		return getSubject(null);
	}

	public String getSubject(String paramString) {
		Subject localSubject = getMessageSubject(paramString);
		return localSubject == null ? null : localSubject.subject;
	}

	private Subject getMessageSubject(String paramString) {
		paramString = determineLanguage(paramString);
		for (Subject localSubject : this.subjects) {
			if (paramString.equals(localSubject.language)) {
				return localSubject;
			}
		}
		return null;
	}

	public Collection<Subject> getSubjects() {
		return Collections.unmodifiableCollection(this.subjects);
	}

	public void setSubject(String paramString) {
		if (paramString == null) {
			removeSubject("");
			return;
		}
		addSubject(null, paramString);
	}

	public Subject addSubject(String paramString1, String paramString2) {
		paramString1 = determineLanguage(paramString1);
		Subject localSubject = new Subject(paramString1, paramString2);
		this.subjects.add(localSubject);
		return localSubject;
	}

	public boolean removeSubject(String paramString) {
		paramString = determineLanguage(paramString);
		for (Subject localSubject : this.subjects) {
			if (paramString.equals(localSubject.language)) {
				return this.subjects.remove(localSubject);
			}
		}
		return false;
	}

	public boolean removeSubject(Subject paramSubject) {
		return this.subjects.remove(paramSubject);
	}

	public Collection<String> getSubjectLanguages() {
		Subject localSubject1 = getMessageSubject(null);
		ArrayList<String> localArrayList = new ArrayList<String>();
		for (Subject localSubject2 : this.subjects) {
			if (!localSubject2.equals(localSubject1)) {
				localArrayList.add(localSubject2.language);
			}
		}
		return Collections.unmodifiableCollection(localArrayList);
	}

	public String getBody() {
		return getBody(null);
	}

	public String getBody(String paramString) {
		Body localBody = getMessageBody(paramString);
		return localBody == null ? null : localBody.message;
	}

	private Body getMessageBody(String paramString) {
		paramString = determineLanguage(paramString);
		for (Body localBody : this.bodies) {
			if (paramString.equals(localBody.language)) {
				return localBody;
			}
		}
		return null;
	}

	public Collection<Body> getBodies() {
		return Collections.unmodifiableCollection(this.bodies);
	}

	public void setBody(String paramString) {
		if (paramString == null) {
			removeBody("");
			return;
		}
		addBody(null, paramString);
	}

	public Body addBody(String paramString1, String paramString2) {
		paramString1 = determineLanguage(paramString1);
		Body localBody = new Body(paramString1, paramString2);
		this.bodies.add(localBody);
		return localBody;
	}

	public boolean removeBody(String paramString) {
		paramString = determineLanguage(paramString);
		for (Body localBody : this.bodies) {
			if (paramString.equals(localBody.language)) {
				return this.bodies.remove(localBody);
			}
		}
		return false;
	}

	public boolean removeBody(Body paramBody) {
		return this.bodies.remove(paramBody);
	}

	public Collection<String> getBodyLanguages() {
		Body localBody1 = getMessageBody(null);
		ArrayList<String> localArrayList = new ArrayList<String>();
		for (Body localBody2 : this.bodies) {
			if (!localBody2.equals(localBody1)) {
				localArrayList.add(localBody2.language);
			}
		}
		return Collections.unmodifiableCollection(localArrayList);
	}

	public String getThread() {
		return this.thread;
	}

	public void setThread(String paramString) {
		this.thread = paramString;
	}

	public String getLanguage() {
		return this.language;
	}

	public void setLanguage(String paramString) {
		this.language = paramString;
	}

	private String determineLanguage(String paramString) {
		paramString = "".equals(paramString) ? null : paramString;

		if ((paramString == null) && (this.language != null)) {
			return this.language;
		}
		if (paramString == null) {
			return getDefaultLanguage();
		}

		return paramString;
	}

	@SuppressWarnings("rawtypes")
    public String toXML() {
		StringBuilder localStringBuilder = new StringBuilder();
		localStringBuilder.append("<message");
		if (getXmlns() != null) {
			localStringBuilder.append(" xmlns=\"").append(getXmlns()).append("\"");
		}
		if (this.language != null) {
			localStringBuilder.append(" xml:lang=\"").append(getLanguage()).append("\"");
		}
		if (getPacketID() != null) {
			localStringBuilder.append(" id=\"").append(getPacketID()).append("\"");
		}
		if (getTo() != null) {
			localStringBuilder.append(" to=\"").append(StringUtils.escapeForXML(getTo())).append("\"");
		}
		if (getFrom() != null) {
			localStringBuilder.append(" from=\"").append(StringUtils.escapeForXML(getFrom())).append("\"");
		}
		if (this.type != Type.normal) {
			localStringBuilder.append(" type=\"").append(this.type).append("\"");
		}
		localStringBuilder.append(">");

		Subject localSubject = getMessageSubject(null);
		if (localSubject != null) {
			localStringBuilder.append("<subject>").append(StringUtils.escapeForXML(localSubject.subject))
					.append("</subject>");
		}

		Object localObject1 = null;
		Object localObject2 = null;
		for (localObject1 = getSubjects().iterator(); ((Iterator) localObject1).hasNext();) {
			localObject2 = (Subject) ((Iterator) localObject1).next();

			if (((Subject) localObject2).equals(localSubject))
				continue;
			localStringBuilder.append("<subject xml:lang=\"").append(((Subject) localObject2).language).append("\">");
			localStringBuilder.append(StringUtils.escapeForXML(((Subject) localObject2).subject));
			localStringBuilder.append("</subject>");
		}

		localObject1 = getMessageBody(null);
		if (localObject1 != null) {
			localStringBuilder.append("<body>").append(StringUtils.escapeForXML(((Body) localObject1).message))
					.append("</body>");
		}

		for (localObject2 = getBodies().iterator(); ((Iterator) localObject2).hasNext();) {
			Body localBody = (Body) ((Iterator) localObject2).next();

			if (localBody.equals(localObject1))
				continue;
			localStringBuilder.append("<body xml:lang=\"").append(localBody.getLanguage()).append("\">");
			localStringBuilder.append(StringUtils.escapeForXML(localBody.getMessage()));
			localStringBuilder.append("</body>");
		}
		if (this.thread != null) {
			localStringBuilder.append("<thread>").append(this.thread).append("</thread>");
		}

		if (this.type == Type.error) {
			localObject2 = getError();
			if (localObject2 != null) {
				localStringBuilder.append(((XMPPError) localObject2).toXML());
			}
		}

		localStringBuilder.append(getExtensionsXML());
		localStringBuilder.append("</message>");
		return  (String) localStringBuilder.toString();
	}

	public boolean equals(Object paramObject) {
		if (this == paramObject)
			return true;
		if ((paramObject == null) || (getClass() != paramObject.getClass()))
			return false;

		MyMessage localMessage = (MyMessage) paramObject;

		if (!super.equals(localMessage))
			return false;
		if ((this.bodies.size() != localMessage.bodies.size()) || (!this.bodies.containsAll(localMessage.bodies))) {
			return false;
		}
		if (this.language != null ? !this.language.equals(localMessage.language) : localMessage.language != null) {
			return false;
		}
		if ((this.subjects.size() != localMessage.subjects.size())
				|| (!this.subjects.containsAll(localMessage.subjects))) {
			return false;
		}
		if (this.thread != null ? !this.thread.equals(localMessage.thread) : localMessage.thread != null) {
			return false;
		}
		return this.type == localMessage.type;
	}

	public int hashCode() {
		int i = this.type != null ? this.type.hashCode() : 0;
		i = 31 * i + this.subjects.hashCode();
		i = 31 * i + (this.thread != null ? this.thread.hashCode() : 0);
		i = 31 * i + (this.language != null ? this.language.hashCode() : 0);
		i = 31 * i + this.bodies.hashCode();
		return i;
	}

	public static enum Type {
		normal,

		chat,

		groupchat,

		headline,

		error,

		push;

		public static Type fromString(String paramString) {
			try {
				return valueOf(paramString);
			} catch (Exception localException) {
			}
			return normal;
		}
	}

	public static class Body {
		private String message;
		private String language;

		private Body(String paramString1, String paramString2) {
			if (paramString1 == null) {
				throw new NullPointerException("Language cannot be null.");
			}
			if (paramString2 == null) {
				throw new NullPointerException("Message cannot be null.");
			}
			this.language = paramString1;
			this.message = paramString2;
		}

		public String getLanguage() {
			return this.language;
		}

		public String getMessage() {
			return this.message;
		}

		public int hashCode() {
			int i = 1;
			i = 31 * i + this.language.hashCode();
			i = 31 * i + this.message.hashCode();
			return i;
		}

		public boolean equals(Object paramObject) {
			if (this == paramObject) {
				return true;
			}
			if (paramObject == null) {
				return false;
			}
			if (getClass() != paramObject.getClass()) {
				return false;
			}
			Body localBody = (Body) paramObject;

			return (this.language.equals(localBody.language)) && (this.message.equals(localBody.message));
		}
	}

	public static class Subject {
		private String subject;
		private String language;

		private Subject(String paramString1, String paramString2) {
			if (paramString1 == null) {
				throw new NullPointerException("Language cannot be null.");
			}
			if (paramString2 == null) {
				throw new NullPointerException("Subject cannot be null.");
			}
			this.language = paramString1;
			this.subject = paramString2;
		}

		public String getLanguage() {
			return this.language;
		}

		public String getSubject() {
			return this.subject;
		}

		public int hashCode() {
			int i = 1;
			i = 31 * i + this.language.hashCode();
			i = 31 * i + this.subject.hashCode();
			return i;
		}

		public boolean equals(Object paramObject) {
			if (this == paramObject) {
				return true;
			}
			if (paramObject == null) {
				return false;
			}
			if (getClass() != paramObject.getClass()) {
				return false;
			}
			Subject localSubject = (Subject) paramObject;

			return (this.language.equals(localSubject.language)) && (this.subject.equals(localSubject.subject));
		}
	}
}
